package hh.util.bean.copy;

import hh.util.bean.ClassInfo;
import hh.util.bean.codegen.CopyProxyFactory;
import hh.util.bean.codegen.DefaultCopyProxyFactory;
import hh.util.bean.codegen.FullCodeGenerateCopyProxy;
import hh.util.bean.codegen.JavaBeanCreatorFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @author huanghuai
 * @date 2020/10/26
 */
public class FullCodeGenCopier extends AbstractCopier {
    private static final long serialVersionUID = -3441487741431485807L;
    private Map<Long, FullCodeGenerateCopyProxy> proxyMap = new HashMap<>();

    final CopyProxyFactory defaultCopyProxyFactory = new DefaultCopyProxyFactory();
    CopyProxyFactory copyProxyFactory = defaultCopyProxyFactory;

    public void setCopyProxyFactory(CopyProxyFactory copyProxyFactory) {
        this.copyProxyFactory = copyProxyFactory;
    }

    @Override
    protected <Dest, Source> Dest doCopy(Source sourceObj, Class<Dest> destType) throws Exception {
        Class<?> sourceClass = sourceObj.getClass();
        Long key = (((long) sourceClass.hashCode()) << 32) + destType.hashCode();
        FullCodeGenerateCopyProxy proxy = proxyMap.get(key);
        if (proxy == null) {
            ClassInfo destInfo = getClassInfo(destType);
            proxy = copyProxyFactory.getCopyProxy(sourceClass, destType, destInfo.getJavaBeanFields());
            proxy.setJavaBeanCreator(JavaBeanCreatorFactory.getObject(destType));
            proxyMap.put(key, proxy);
        }
        return (Dest) proxy.copy(sourceObj);
    }

}
